package com.leiqichao.backend.util;

import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.lionsoul.ip2region.xdb.Searcher;
import org.springframework.stereotype.Service;


import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;


@Slf4j
@Service
public class IpLocationService {

    private Searcher searcher;

    @PostConstruct
    public void init() throws IOException {
        final String resourcePath = "/ipdb/ip2region.xdb"; // 统一资源路径定义
        InputStream inputStream = null;
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();

        try {
            // 通过类加载器获取资源流（兼容各种部署环境）
            inputStream = getClass().getResourceAsStream(resourcePath);
            if (inputStream == null) {
                String errorMsg = String.format("IP数据库文件未找到！请确认资源文件已打包到JAR的 %s 路径", resourcePath);
                log.error(errorMsg);
                throw new FileNotFoundException(errorMsg);
            }

            log.info("开始加载IP数据库文件，资源路径: {}", resourcePath);

            // 使用更可靠的流复制方式（替代 available() 方法）
            byte[] data = new byte[4096];
            int bytesRead;
            while ((bytesRead = inputStream.read(data, 0, data.length)) != -1) {
                buffer.write(data, 0, bytesRead);
            }

            // 验证文件完整性（示例：预期文件大小约12MB）
            byte[] cBuff = buffer.toByteArray();
            if (cBuff.length < 1024 * 1024) { // 实际根据文件调整阈值
                throw new IOException("文件大小异常，可能损坏或未正确打包");
            }

            searcher = Searcher.newWithBuffer(cBuff);
            log.info("IP数据库初始化成功，版本: {}，文件大小: {} MB",
                    "",
                    String.format("%.2f", cBuff.length / 1024.0 / 1024.0));
        } catch (Exception e) {
            // 增强错误诊断信息


            throw new RuntimeException("IP服务初始化失败", e);
        } finally {
            // 确保资源关闭
            IOUtils.closeQuietly(inputStream);
            IOUtils.closeQuietly(buffer);
        }
    }

    /**
     * 根据IP获取归属地信息
     * @param ip IP地址
     * @return 归属地信息(国家|省份|城市|ISP)
     */
    public String getIpLocation(String ip) {
        try {
            return searcher.search(ip);
        } catch (Exception e) {
            return "未知|未知|未知|未知";
        }
    }

    /**
     * 获取格式化的归属地(国家/省份/城市)
     * @param ip IP地址
     * @return 格式化的字符串，如 "中国/广东省/深圳市"。如果解析失败，返回 "未知"。
     */
    public String getFormattedIpLocation(String ip) {
        // 1. 检查IP是否有效
        if (ip == null || ip.trim().isEmpty()) {
            log.warn("无效的IP地址: {}", ip);
            return "未知";
        }

        // 2. 获取原始位置信息
        String location;
        try {
            // 临时添加测试代码
            log.info("测试IP 8.8.8.8 结果: {}", getIpLocation("8.8.8.8"));
            log.info("正在解析IP位置信息: {}", ip);
            location = getIpLocation(ip);
            log.info("解析到IP位置信息: {}", location);
        } catch (Exception e) {
            log.error("IP位置解析失败: ip={}", ip, e);
            return "未知";
        }

        // 3. 检查location是否有效
        if (location == null || location.trim().isEmpty()) {
            log.warn("无效的IP位置信息: {}", location);
            return "未知";
        }

        // 4. 安全分割和处理
        String[] parts = location.split("\\|");
        String country = (parts.length > 0 && !parts[0].isEmpty()) ? parts[0] : "未知";
        String province = (parts.length > 2 && !parts[2].isEmpty()) ? parts[2] : "未知";
        String city = (parts.length > 3 && !parts[3].isEmpty()) ? parts[3] : "未知";

        // 5. 格式化输出
        return String.format("%s/%s/%s", country, province, city);
    }
}